<?php
declare(strict_types=1);

namespace SixShop\Wechat\Service;

use SixShop\Wechat\Entity\WechatDeliveryEntity;
use think\Collection;
use think\facade\Log;
use function SixShop\Core\throw_logic_exception;

class ExpressService
{
    public function __construct(private MiniApp $miniApp, private WechatDeliveryEntity $wechatDeliveryEntity)
    {
    }

    /**
     * 获取所有快递公司
     */
    public function getAllDelivery(): Collection
    {
        $result = $this->wechatDeliveryEntity->select();
        if ($result->isEmpty()) {
            $response = $this->miniApp->getClient()->get('/cgi-bin/express/business/delivery/getall');
            if ($response->isFailed()) {
                Log::error('获取所有快递公司失败' . json_encode($response->toArray()));
                throw_logic_exception('获取所有快递公司失败');
            }
            $result = $response->toArray();
            $result = $this->wechatDeliveryEntity->saveAll($result['data']);
        }
        return $result;
    }

    /**
     * 查询订单发货状态
     *
     * @link https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%89%E3%80%81%E6%9F%A5%E8%AF%A2%E8%AE%A2%E5%8D%95%E5%8F%91%E8%B4%A7%E7%8A%B6%E6%80%81
     */
    public function queryOrder(string $transactionID): array
    {
        $response = $this->miniApp->getClient()->postJson('/wxa/sec/order/get_order', [
            'transaction_id' => $transactionID,
        ]);
        if ($response->isFailed()) {
            $responseData = $response->toArray();
            Log::error('查询订单发货状态失败{transaction_id}{response}', ['transaction_id' => $transactionID, 'response' => json_encode($responseData)]);
            throw_logic_exception(msg: '查询订单发货状态失败', code: $responseData['errcode']);
        }
        return $response->toArray()['order'];
    }

    /**
     * 发货信息录入
     *
     * 使用微信支付单号
     *
     * @param string $transactionID 微信支付单号
     * @param string $openid 用户openid
     * @param array $shippingList 订单发货信息
     * @param int $logisticsType 物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
     * @param int $deliveryMode 发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY
     *
     * @link https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
     */
    public function uploadShippingInfo(
        string $transactionID,
        string $openid,
        array  $shippingList,
        int    $logisticsType = 1,
        int    $deliveryMode = 1,
        bool   $isAllDelivered = false,
    ): void
    {
        $data = [
            'order_key' => [
                'order_number_type' => 2, // 使用微信支付单号
                'transaction_id' => $transactionID,
            ],
            'logistics_type' => $logisticsType,
            'delivery_mode' => $deliveryMode,
            'is_all_delivered' => $isAllDelivered,
            'shipping_list' => $shippingList,
            'upload_time' => date('c'),
            'payer' => [
                'openid' => $openid,
            ],
        ];
        $response = $this->miniApp->getClient()->postJson('/wxa/sec/order/upload_shipping_info', $data);
        if ($response->isFailed()) {
            $responseData = $response->toArray();
            Log::error('发货信息录入失败 {transaction_id} {response} {request}', [
                'transaction_id' => $transactionID,
                'response' => json_encode($responseData),
                'request' => json_encode($data),
            ]);
            throw_logic_exception(msg: '发货信息录入失败', code: $responseData['errcode']);
        }
    }
}